package sfeir.gwt.ergosoom.server;

import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.resource.Finder;
import org.restlet.resource.ServerResource;
import org.restlet.routing.Router;

import sfeir.gwt.ergosoom.server.guice.FinderFactory;
import sfeir.gwt.ergosoom.server.guice.FinderFactoryModule;
import sfeir.gwt.ergosoom.server.service.rest.BackupService;
import sfeir.gwt.ergosoom.server.service.rest.ProfileService;
import sfeir.gwt.ergosoom.server.service.rest.RegisterService;

import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.name.Names;

public class RestletApplication extends Application implements Module {

    private static final String RESOURCE_REGISTER = "resource.register";
    private static final String RESOURCE_PROFILE = "resource.profile";
    private static final String RESOURCE_BACKUP = "resource.backup";

    private ThreadLocal<FinderFactory> factory = new ThreadLocal<FinderFactory>() {
        protected FinderFactory initialValue() {
            return Guice.createInjector(new FinderFactoryModule(RestletApplication.this)).getInstance(
                    FinderFactory.class);
        };
    };

    /**
     * Creates a root Restlet that will receive all incoming calls.
     */
    @Override
    public synchronized Restlet createRoot() {
        Router router = new Router(getContext());

        // Defines only one route
        // router.attachDefault(RegisterService.class);
        // router.attach("/register", RegisterService.class);
        // router.attach("/confirm/{code}", RegisterService.class);
        // router.attach("/profile/{alias}/{passwd}", ProfileService.class);
        // router.attach("/backup/{alias}/{passwd}", BackupService.class);
        Finder registerFinder = getFinder(RESOURCE_REGISTER);
        router.attach("/register", registerFinder);
        router.attach("/confirm/{code}", registerFinder);
        router.attach("/profile/{alias}/{passwd}", getFinder(RESOURCE_PROFILE));
        router.attach("/backup/{alias}/{passwd}", getFinder(RESOURCE_BACKUP));

        return router;
    }

    @Override
    public void configure(Binder binder) {
        binder.bind(ServerResource.class).annotatedWith(Names.named(RESOURCE_REGISTER)).to(RegisterService.class);
        binder.bind(ServerResource.class).annotatedWith(Names.named(RESOURCE_PROFILE)).to(ProfileService.class);
        binder.bind(ServerResource.class).annotatedWith(Names.named(RESOURCE_BACKUP)).to(BackupService.class);
    }

    private Finder getFinder(String resourceName) {
        return factory.get().finderFor(Key.get(ServerResource.class, Names.named(resourceName)));
    }
}
